package com.lipaluma.io.xml;

import static org.joox.JOOX.*;

import java.util.ArrayList;
import java.util.List;

import org.joox.Match;
import org.w3c.dom.Element;

import com.lipaluma.field.mapper.mapping.MappingInfo;
import com.lipaluma.field.mapper.mapping.Path;
import com.lipaluma.io.PathRow;
import com.lipaluma.io.Row;
public class XmlRow implements PathRow {

	private Element element;
	
	public XmlRow() {}
	public XmlRow(Element element) {
		this.element = element;
	}
	
	
	@Override
	public String extractValue(MappingInfo info) {
		Path path = (Path)info;
		return $(element).xpath(path.getPath()).text();
	}

	@Override
	public List<? extends PathRow> extractSubRows(MappingInfo mapping) {
		Path path = (Path)mapping;
		List<XmlRow> xmlSubRows = new ArrayList<XmlRow>();
		for(Match match : $(element).children(path.getPath()).each()){
			Element element = match.document().getDocumentElement();
			xmlSubRows.add(new XmlRow(element));
		}
		return xmlSubRows;
	}
	
	@Override
	public PathRow getExistingOrCreateOnlyParentRow(String path) {
		String[] names = path.split("/");
		Match current = $(element);
		for (int i = 0; i < names.length -1; i++) {
			if(!current.children().is(names[i]))
				current = $(current).append($(names[i])).children(names[i]).last();
			else 
				current = current.child(names[i]);
		}
		return new XmlRow($(current).get(0));
	}
	
	@Override
	public PathRow createNewLeafRow(String path) {
		String[] names = path.split("/");
		
		Element subElement = $(element).append($(names[names.length - 1])).children(names[names.length - 1]).last().get(0);
		XmlRow xmlRow = new XmlRow();
		xmlRow.element = subElement;
		return xmlRow;
	}
	
	@Override
	public void writeValue(Object value, MappingInfo info) {
		Path path = (Path)info;
		Match toAdd = $(path.getPath());
		if(value != null)
			toAdd.after(String.valueOf(value));
		$(element).append(toAdd);
	}

	@Override
	public String[] toArray() {
		// TODO Auto-generated method stub
		return null;
	}
	
	public Element getElement() {
		return element;
	}
}
